// 游戏总逻辑函数
const WORLD_WIIDTH = 100;
const WORLD_HEIGHT = 30;
const SPEED_SCALE_INCREASE = 0.0000001; // 游戏难度基础系数值

import { updateGround, setupGround } from "./ground.js";
import { updateDino, setupDino, getDinoRect, setDinoLose } from "./dino.js";
import { updateCactus, setupCactus, getCactusRects } from "./cactus.js";

const worldElem = document.querySelector("[data-world]");
const startScreenElem = document.querySelector("[data-start-screen]");
const scoreElem = document.querySelector("[data-score]");

setPixelToWorldScale(); // 初始化游戏世界的大小
window.addEventListener("resize", setPixelToWorldScale);
document.addEventListener("keydown", handleStart, { once: true });

let lastTime;
let speedScale;
let score;

// 动画执行函数
function update(time) {
  if (lastTime == null) {
    lastTime = time;
    window.requestAnimationFrame(update);
    return;
  }

  const delta = time - lastTime; // 每帧动画的时间差是核心，因为每一帧的动画牵连很多元素，所以传入的时间差必须一致，这样才能控制动画元素在执行动画时动作保持一致，不会产生卡顿

  updateSpeedScale(delta);
  updateGround(delta, speedScale);
  updateScore(delta);
  updateDino(delta, speedScale);
  updateCactus(delta, speedScale);

  if (checkLose()) return handleLose();

  lastTime = time;
  window.requestAnimationFrame(update);
}

// 游戏结束后的处理
function handleLose() {
  setDinoLose();

  setTimeout(() => {
    document.addEventListener("keydown", handleStart, { once: true });
    startScreenElem.classList.remove("hide");
  }, 100);
}

// 判断是否游戏结束
function checkLose() {
  const dinoRect = getDinoRect();
  return getCactusRects().some((rect) => isCollision(rect, dinoRect));
}

// 修改游戏难度系数（随着时间的推移难度系数值越大，地面的移动速度越快）
function updateSpeedScale(delta) {
  speedScale += delta * SPEED_SCALE_INCREASE;
}

// 修改游戏得分(分数是随着游戏的时间来叠加的)
function updateScore(delta) {
  score += delta * 0.001;
  scoreElem.textContent = Math.floor(score);
}

// 通过判断小恐龙和仙人掌是否碰撞
function isCollision(rect1, rect2) {
  return (
    rect1.left < rect2.right &&
    rect1.top < rect2.bottom &&
    rect1.right > rect2.left &&
    rect1.bottom > rect2.top
  );
}

// 按下任意键开始游戏
function handleStart() {
  lastTime = null;
  speedScale = 1;
  score = 0;

  setupGround();
  setupDino();
  setupCactus();

  startScreenElem.classList.add("hide");
  window.requestAnimationFrame(update);
}

function setPixelToWorldScale() {
  let worldToPixeScale = 0;

  /**
   * 判断视口的大小是否大于我们自定义的常量，这样做主要是保证我们的游戏世界的元素大小在视口的中央
   *
   * 当视口宽度大于高度时，判断结果为false，就取高度做计算
   * 当视口宽度小于高度时，判断结果为true，就取宽度做计算
   */
  if (window.innerWidth / window.innerHeight < WORLD_WIIDTH / WORLD_HEIGHT) {
    worldToPixeScale = window.innerWidth / WORLD_WIIDTH;
  } else {
    worldToPixeScale = window.innerHeight / WORLD_HEIGHT;
  }

  worldElem.style.width = `${WORLD_WIIDTH * worldToPixeScale}px`;
  worldElem.style.height = `${WORLD_HEIGHT * worldToPixeScale}px`;
}
